#!/usr/bin/python

import os, sys
import xml.etree.cElementTree as ET
from Cheetah.Template import Template
from urllib import quote_plus
from glob import glob
import traceback
import re
from xml.sax.saxutils import escape
import codecs
from xml.sax.saxutils import quoteattr

# optimizations
try:
    import psyco
    psyco.full()
except:
    print "No runtime optimization."
    pass

# templates
DEFAULT_OUTPUT="output.turtle"
TEMPLATE_DIR="templates"
SOFTWARE_NAMESPACE="http://mephistopedia.net/"

templates = {}
for t in ["software.csv", "binary-package.csv", "package-dependencies.csv", "package-files.csv", "header.n3", "software.n3", "binary-package.n3", "software-version.n3", "source-package.n3"]:
    templates[t] = open("%s/%s" % (TEMPLATE_DIR, t)).read()

class File:
    def __init__(self, path, type, size):
        self.path = path
        self.type = type
        self.size = size
       


def parse_package_metadata(file, software_out, binary_packages_out, package_files_out, package_dependencies_out, source_packages_out):
    """Parses package metadata files and outputs valid turtle format"""
    data = codecs.open( file, "r").read()

    try:
        res = ET.fromstring(data)
    except SyntaxError:
        # looks like we found an invalid character
        print >>sys.stderr, "Invalid characters found, stripping..",
        # this is slow, but it is the best we can do right now..
        #for match in regex.finditer(data):
        #    data = data[:match.start()] + "?" + data[match.end():]
        #res = ET.fromstring(data)
        return
    
    for package in res:
        params = {}
        # process package parameters
        # XPATH
        params["filename"] = package.get("filename")
        params["namespace"] = SOFTWARE_NAMESPACE
        params["name"] = package.findtext("./name")
        params["license"] = package.findtext("./license")
        params["url"] = package.findtext("./homepage")
        params["description"] = package.findtext("./description").replace("\"","\\\"").replace("\n"," ")
        print >>software_out, templates["software.csv"] % params
        
        #info = get_template('binary-package.n3')
        info = get_template('binary-package.csv')
        
        info.name = params["name"]
        scripts = package.find("./scripts")
        info.filename = params["filename"]
        info.prein = scripts.findtext("./prein").replace("\"","\\\"").replace("\n"," ")
        info.postin = scripts.findtext("./postin").replace("\"","\\\"").replace("\n"," ")
        info.preun = scripts.findtext("./preun").replace("\"","\\\"").replace("\n"," ")
        info.postun = scripts.findtext("./postun").replace("\"","\\\"").replace("\n"," ")
        info.namespace = SOFTWARE_NAMESPACE
        info.distrib = "mandriva/cooker"
        info.version = package.findtext("./version")
        info.release = package.findtext("./release")
        info.architecture = package.findtext("./arch")
        info.group = package.findtext("./group")
        info.sourcerpm = package.findtext("./sourcerpm")
        info.buildhost = package.findtext("./buildhost")
        info.buildtime = package.findtext("./buildtime")
        info.size = package.findtext("./size")
        info.packager = package.findtext("./packager")
        info.summary = package.findtext("./summary").replace("\"","\\\"")
        info.description = params["description"]
        info.license = params["license"]
        info.home = params["url"]
        info.size = package.findtext("./size")
        
        print >>binary_packages_out, str(info)
        
        info = get_template('package-dependencies.csv')
        info.filename = params["filename"]
        info.distrib = "mandriva/cooker"
        for provide in package.findall("./provides"):
           info.item = provide.text
           info.dep = "provides"
           print >>package_dependencies_out, str(info)
        
        for require in package.findall("./requires"):
            info.item = require.text
            info.dep = "requires"
            print >>package_dependencies_out, str(info)        
        
        info = get_template('package-files.csv')

        info.files = []
        info.filename = params["filename"]
        info.distrib = "mandriva/cooker"
        for file in package.findall("./file"):
            info.path= file.get("path")
            info.type = file.get("type")
            info.size = file.get("size")
            print >>package_files_out, str(info)

        
        #params["distrib"] = info.distrib
        #params["version"] = info.version
        #params["sourcerpm"] = info.sourcerpm
        #print >>output, templates["source-package.n3"] % params
        
        #print >>output, templates["software-version.n3"] % params

    
        
def get_template(file_name):
    path = os.path.join('.', 'templates', file_name)
    tmpl = Template(file=path, filter='EncodeUnicode')
    return tmpl
        
        
if __name__ == "__main__":
    if len(sys.argv) < 7:
        print "Usage: %s <package metadata dir> <software-file> <bin-packages-csv-file> <package-files-csv-file> <package-dependencies-csv-file> <source-packages-csv-file>" % sys.argv[0]
        sys.exit(1)
    package_dir = sys.argv[1]
    if len(sys.argv) >= 6:
        software_out = open(sys.argv[2], "w")
        binary_packages_out = open(sys.argv[3], "w")
        package_files_out = open(sys.argv[4], "w")
        package_dependencies_out = open(sys.argv[5], "w")
        source_packages_out = open(sys.argv[6], "w")
        one_big_file = True
    else:
        output = None
        one_big_file = False
    
    # looking for files
    metadata_files = []
    
    for dirs in os.listdir(package_dir):
        dir_path = os.path.join(package_dir,dirs)
        for metadata_file in os.listdir(dir_path):
            if (metadata_file == 'metadata.xml'):
                metadata_files.append(os.path.join(dir_path, metadata_file))
                

    #if one_big_file:
    #  print >> output, templates["header.n3"]
    
    for file in metadata_files:
        # are we doing one file at a time?
        if not one_big_file:
            newfile_l = file.split(".")
            newfile_l[-1] = "turtle"
            newfile = ".".join(newfile_l)
            output = open(newfile, "w")
        print >>sys.stderr, "Parsing %s.." % file,
        try:
            parse_package_metadata(file, software_out, binary_packages_out, package_files_out, package_dependencies_out, source_packages_out )
            print >>sys.stderr, "ok"
#           os.unlink(file)
        except:
            traceback.print_exc()
            print >>sys.stderr, "error parsing %s: %s" % (file, sys.exc_value)
            sys.exit(1)
        if not one_big_file:
            output.close()

#    print files
